{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## MNIST CNN"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from fastai.vision.all import *"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "path = untar_data(URLs.MNIST)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(#4) [/home/sgugger/.fastai/data/mnist_png/models,/home/sgugger/.fastai/data/mnist_png/testing,/home/sgugger/.fastai/data/mnist_png/resnet34_mnist.pkl,/home/sgugger/.fastai/data/mnist_png/training]"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "path.ls()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "PosixPath('/home/sgugger/.fastai/data/mnist_png/testing/1/6540.png')"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "items = get_image_files(path)\n",
    "items[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAOcAAADnCAYAAADl9EEgAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAEi0lEQVR4nO3dvUqcWxSA4eNh8kNAEFJIGovUWuQibIZ0XlAuJwETUsUqeBl2KRUsBCWk0YQ5N2D24HFG30+ep3QhbAgvC7LZnxuLxeIfoOffxz4AcDtxQpQ4IUqcECVOiJotmfuvXFi/jdt+aHNClDghSpwQJU6IEidEiROixAlR4oQocUKUOCFKnBAlTogSJ0SJE6LECVHihChxQpQ4IUqcECVOiBInRIkTosQJUeKEKHFClDghSpwQJU6IEidEiROixAlR4oQocUKUOCFKnBAlTogSJ0SJE6Jmj30A7ub6+no4f/369XD+/v374fzjx493PhPrYXNClDghSpwQJU6IEidEiROixAlRG4vFYjQfDnl4Ozs7w/np6elwvrm5OZxfXl7e+Uzc28ZtP7Q5IUqcECVOiBInRIkTosQJUZ6MTczu7u5wfnZ29kAnYd1sTogSJ0SJE6LECVHihChxQpQ4IcqTsYn5/v37cD6fz4fzV69eDeeejD0KT8ZgSsQJUeKEKHFClDghSpwQJU6I8p5zYpa911xyb82E2JwQJU6IEidEiROixAlR4oQocUKU95xPzNbW1r1+33vOR+E9J0yJOCFKnBAlTogSJ0SJE6LECVHec07MxcXFcH5zczOcP3v2bJXHYY1sTogSJ0SJE6LECVHihChxQpSrlIk5PDwczn///j2cL/t05vn5+V9n29vbw99ltWxOiBInRIkTosQJUeKEKHFClDghyqcxn5hln8a8uroazj9//vzX2cHBwf86E0v5NCZMiTghSpwQJU6IEidEiROixAlR3nM+MfP5fDj/9OnTA52E+7I5IUqcECVOiBInRIkTosQJUeKEKPecT8yy79LOZuN/8nfv3q3yONyDzQlR4oQocUKUOCFKnBAlTogSJ0S555yY6+vr4fzbt2/D+Z8/f4bzHz9+/HX29u3b4e+yWjYnRIkTosQJUeKEKHFClDghylXKxJycnAznNzc3w/nm5uZwvr+/f+czsR42J0SJE6LECVHihChxQpQ4IUqcEOWec2K+fv06nC97UvbixYtVHoc1sjkhSpwQJU6IEidEiROixAlR4oQo95wTs7e399hH4IHYnBAlTogSJ0SJE6LECVHihChxQtTGYrEYzYdDHt7Pnz+H8zdv3gzns9n4avvy8vLOZ+LeNm77oc0JUeKEKHFClDghSpwQJU6I8mRsYpZ9+nI+nw/nFxcXqzwOa2RzQpQ4IUqcECVOiBInRIkTosQJUe45J+bDhw/D+ZcvX4bzX79+rfI4rJHNCVHihChxQpQ4IUqcECVOiBInRLnnnJjnz58P58fHx8P5y5cvV3kc1sjmhChxQpQ4IUqcECVOiBInRIkTovwJwInZ2dkZzo+Ojobz3d3dVR6H1fAnAGFKxAlR4oQocUKUOCFKnBAlTohyzwmPzz0nTIk4IUqcECVOiBInRIkTosQJUeKEKHFClDghSpwQJU6IEidEiROixAlR4oQocUKUOCFKnBAlTogSJ0SJE6JmS+a3frIPWD+bE6LECVHihChxQpQ4IUqcEPUfI+WMO0DgEWoAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "im = PILImageBW.create(items[0])\n",
    "im.show();"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "splits = GrandparentSplitter(train_name='training', valid_name='testing')(items)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "dsets = Datasets(items, tfms=[[PILImageBW.create], [parent_label, Categorize]], splits=splits)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(#70000) [(<fastai.vision.core.PILImageBW image mode=L size=28x28 at 0x7EFFA4FE4C50>, tensor(1)),(<fastai.vision.core.PILImageBW image mode=L size=28x28 at 0x7EFFA4FC9910>, tensor(1)),(<fastai.vision.core.PILImageBW image mode=L size=28x28 at 0x7EFFA4DA1850>, tensor(1)),(<fastai.vision.core.PILImageBW image mode=L size=28x28 at 0x7EFFA4DA19D0>, tensor(1)),(<fastai.vision.core.PILImageBW image mode=L size=28x28 at 0x7EFFA4DA1B10>, tensor(1)),(<fastai.vision.core.PILImageBW image mode=L size=28x28 at 0x7EFFA4DA1C50>, tensor(1)),(<fastai.vision.core.PILImageBW image mode=L size=28x28 at 0x7EFFA4DA1D90>, tensor(1)),(<fastai.vision.core.PILImageBW image mode=L size=28x28 at 0x7EFFA4DA1ED0>, tensor(1)),(<fastai.vision.core.PILImageBW image mode=L size=28x28 at 0x7EFFA4DA1FD0>, tensor(1)),(<fastai.vision.core.PILImageBW image mode=L size=28x28 at 0x7EFFA4DA1BD0>, tensor(1))...]"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dsets"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(#60000) [(<fastai.vision.core.PILImageBW image mode=L size=28x28 at 0x7EFFA4DABB10>, tensor(1)),(<fastai.vision.core.PILImageBW image mode=L size=28x28 at 0x7EFFA4DABC50>, tensor(1)),(<fastai.vision.core.PILImageBW image mode=L size=28x28 at 0x7EFFA4DABD90>, tensor(1)),(<fastai.vision.core.PILImageBW image mode=L size=28x28 at 0x7EFFA4DABED0>, tensor(1)),(<fastai.vision.core.PILImageBW image mode=L size=28x28 at 0x7EFFA4DABFD0>, tensor(1)),(<fastai.vision.core.PILImageBW image mode=L size=28x28 at 0x7EFFA4DABBD0>, tensor(1)),(<fastai.vision.core.PILImageBW image mode=L size=28x28 at 0x7EFFA4DAF1D0>, tensor(1)),(<fastai.vision.core.PILImageBW image mode=L size=28x28 at 0x7EFFA4DAF410>, tensor(1)),(<fastai.vision.core.PILImageBW image mode=L size=28x28 at 0x7EFFA4DAF550>, tensor(1)),(<fastai.vision.core.PILImageBW image mode=L size=28x28 at 0x7EFFA4DAF690>, tensor(1))...]"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dsets.train"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(#10000) [(<fastai.vision.core.PILImageBW image mode=L size=28x28 at 0x7EFFA56D7F90>, tensor(1)),(<fastai.vision.core.PILImageBW image mode=L size=28x28 at 0x7EFFA4DAFE90>, tensor(1)),(<fastai.vision.core.PILImageBW image mode=L size=28x28 at 0x7EFFA4DAF0D0>, tensor(1)),(<fastai.vision.core.PILImageBW image mode=L size=28x28 at 0x7EFFA4DAF110>, tensor(1)),(<fastai.vision.core.PILImageBW image mode=L size=28x28 at 0x7EFFA4DAFFD0>, tensor(1)),(<fastai.vision.core.PILImageBW image mode=L size=28x28 at 0x7EFFA4DAB0D0>, tensor(1)),(<fastai.vision.core.PILImageBW image mode=L size=28x28 at 0x7EFFA4DABF50>, tensor(1)),(<fastai.vision.core.PILImageBW image mode=L size=28x28 at 0x7EFFA4DABDD0>, tensor(1)),(<fastai.vision.core.PILImageBW image mode=L size=28x28 at 0x7EFFA4DABC90>, tensor(1)),(<fastai.vision.core.PILImageBW image mode=L size=28x28 at 0x7EFFA4DABB50>, tensor(1))...]"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dsets.valid"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAOcAAAD3CAYAAADmIkO7AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAFA0lEQVR4nO3dv2qVZxzA8ec1IhYEcXALgk7OUvAS6pLFuZfQwbFDcJDu3kL1Ajp6EVIkm5OIIJ0CGhBK/MPp0FIoJG+q5+j55uTzmUJ+JHlAvv5CHt5zpsViMYCec+s+AHA0cUKUOCFKnBAlTogSJ0SJE6LEuQGmafppmqbfp2k6nKbp13Wfh9U4v+4DsBJ/jDF+GWP8MMb4bs1nYUXEuQEWi8VvY4wxTdP3Y4ztNR+HFfFrLUSJE6LECVHihCh/ENoA0zSdH3//W26NMbamabo4xvi4WCw+rvdkLMPm3Ay7Y4w/xxg/jzF+/Ofj3bWeiKVNHraGJpsTosQJUeKEKHFC1ElXKf5aBF/fdNQnbU6IEidEiROixAlR4oQocUKUOCFKnBAlTogSJ0SJE6LECVHihChxQpQ4IUqcECVOiBInRIkTosQJUeKEKHFClDghSpwQJU6IEidEiROixAlR4oQocUKUOCFKnBAlTogSJ0SJE6LECVHihChxQtT5dR+A//r06dPs/MWLF7Pze/fuzc6fPHny2WdiPWxOiBInRIkTosQJUeKEKHFClDghyj1nzOHh4ez85s2bs/Pt7e3Z+bt372bnly5dmp3z7dicECVOiBInRIkTosQJUeKEKFcpG+b169ez84ODg9m5q5QOmxOixAlR4oQocUKUOCFKnBAlTohyz7lhFovFuo/AiticECVOiBInRIkTosQJUeKEKHFClHvODTNN0+z8pJfepMPmhChxQpQ4IUqcECVOiBInRIkTotxznjF7e3uz8xs3bnyjk3ASmxOixAlR4oQocUKUOCFKnBAlTohyzxlz7tz8/5dXrlyZnb9582Z2/vz5888+E+thc0KUOCFKnBAlTogSJ0SJE6JcpcRcvHhxdr6zszM7f/z48SqPwxrZnBAlTogSJ0SJE6LECVHihChxQpQ4IUqcECVOiBInRIkTosQJUeKEKHFClOc5z5j9/f11H4H/yeaEKHFClDghSpwQJU6IEidEiROi3HOeMY8ePZqdP3z48BudhJPYnBAlTogSJ0SJE6LECVHihChxQpR7zlPmzp07s3Pvz7k5bE6IEidEiROixAlR4oQocUKUq5RT5vr160t9/fv372fnBwcHx84uX7681M/m89icECVOiBInRIkTosQJUeKEKHFClHvOU2Zra2upr18sFrPzDx8+LPX9WR2bE6LECVHihChxQpQ4IUqcECVOiJpOuPeavxQj59atW7Pzvb292fnu7u6xswcPHnzRmTjRdNQnbU6IEidEiROixAlR4oQocUKUOCHK85wb5u7du7Pzly9fzs7v37+/yuOwBJsTosQJUeKEKHFClDghSpwQ5SrljJmmI59O+teyL73J6ticECVOiBInRIkTosQJUeKEKHFClHvOM+bt27ez86dPnx47u3379qqPwwybE6LECVHihChxQpQ4IUqcECVOiPIWgBvm2rVrs/P9/f3Z+atXr46dXb169YvOxIm8BSCcJuKEKHFClDghSpwQJU6IEidEeZ5zw+zs7MzOnz17Nju/cOHCKo/DEmxOiBInRIkTosQJUeKEKHFClDghyvOcsH6e54TTRJwQJU6IEidEiROixAlR4oQocUKUOCFKnBAlTogSJ0SJE6LECVHihChxQpQ4IUqcECVOiBInRIkTosQJUSe9BeCRL9kHfH02J0SJE6LECVHihChxQpQ4IeovA3x8nCTpVrIAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "show_at(dsets.train, 0);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "tfms = [ToTensor(), CropPad(size=34, pad_mode=PadMode.Zeros), RandomCrop(size=28)]\n",
    "bs = 128"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "dls = dsets.dataloaders(bs=bs, after_item=tfms, after_batch=[IntToFloatTensor, Normalize])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "dsrc1 = Datasets([items[0]]*128, tfms=[[PILImageBW.create], [parent_label, Categorize]], splits=[list(range(128)), []])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "dbunch1 = dsrc1.dataloaders(bs=bs, after_item=tfms, after_batch=[IntToFloatTensor()])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 576x576 with 9 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "dbunch1.show_batch(figsize=(8,8), cmap='gray')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 360x360 with 9 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "dls.show_batch(figsize=(5,5))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(torch.Size([128, 1, 28, 28]), torch.Size([128]))"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "xb,yb = dls.one_batch()\n",
    "xb.shape,yb.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Basic CNN with batchnorm"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def conv(ni,nf): return nn.Conv2d(ni, nf, kernel_size=3, stride=2, padding=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "model = nn.Sequential(\n",
    "    conv(1, 8), # 14\n",
    "    nn.BatchNorm2d(8),\n",
    "    nn.ReLU(),\n",
    "    conv(8, 16), # 7\n",
    "    nn.BatchNorm2d(16),\n",
    "    nn.ReLU(),\n",
    "    conv(16, 32), # 4\n",
    "    nn.BatchNorm2d(32),\n",
    "    nn.ReLU(),\n",
    "    conv(32, 16), # 2\n",
    "    nn.BatchNorm2d(16),\n",
    "    nn.ReLU(),\n",
    "    conv(16, 10), # 1\n",
    "    nn.BatchNorm2d(10),\n",
    "    Flatten()     # remove (1,1) grid\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "learn = Learner(dls, model, loss_func = nn.CrossEntropyLoss(), metrics=accuracy)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Sequential (Input shape: 128 x 1 x 28 x 28)\n",
      "================================================================\n",
      "Layer (type)         Output Shape         Param #    Trainable \n",
      "================================================================\n",
      "Conv2d               128 x 8 x 14 x 14    80         True      \n",
      "________________________________________________________________\n",
      "BatchNorm2d          128 x 8 x 14 x 14    16         True      \n",
      "________________________________________________________________\n",
      "ReLU                 128 x 8 x 14 x 14    0          False     \n",
      "________________________________________________________________\n",
      "Conv2d               128 x 16 x 7 x 7     1,168      True      \n",
      "________________________________________________________________\n",
      "BatchNorm2d          128 x 16 x 7 x 7     32         True      \n",
      "________________________________________________________________\n",
      "ReLU                 128 x 16 x 7 x 7     0          False     \n",
      "________________________________________________________________\n",
      "Conv2d               128 x 32 x 4 x 4     4,640      True      \n",
      "________________________________________________________________\n",
      "BatchNorm2d          128 x 32 x 4 x 4     64         True      \n",
      "________________________________________________________________\n",
      "ReLU                 128 x 32 x 4 x 4     0          False     \n",
      "________________________________________________________________\n",
      "Conv2d               128 x 16 x 2 x 2     4,624      True      \n",
      "________________________________________________________________\n",
      "BatchNorm2d          128 x 16 x 2 x 2     32         True      \n",
      "________________________________________________________________\n",
      "ReLU                 128 x 16 x 2 x 2     0          False     \n",
      "________________________________________________________________\n",
      "Conv2d               128 x 10 x 1 x 1     1,450      True      \n",
      "________________________________________________________________\n",
      "BatchNorm2d          128 x 10 x 1 x 1     20         True      \n",
      "________________________________________________________________\n",
      "Flatten              128 x 10             0          False     \n",
      "________________________________________________________________\n",
      "\n",
      "Total params: 12,126\n",
      "Total trainable params: 12,126\n",
      "Total non-trainable params: 0\n",
      "\n",
      "Optimizer used: <function Adam at 0x7effc0232440>\n",
      "Loss function: CrossEntropyLoss()\n",
      "\n",
      "Callbacks:\n",
      "  - TrainEvalCallback\n",
      "  - Recorder\n",
      "  - ProgressCallback\n"
     ]
    }
   ],
   "source": [
    "print(learn.summary())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "xb = xb.cuda()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "torch.Size([128, 10])"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model(xb).shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "learn.lr_find(end_lr=100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: left;\">\n",
       "      <th>epoch</th>\n",
       "      <th>train_loss</th>\n",
       "      <th>valid_loss</th>\n",
       "      <th>accuracy</th>\n",
       "      <th>time</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>0</td>\n",
       "      <td>0.213812</td>\n",
       "      <td>0.354680</td>\n",
       "      <td>0.892200</td>\n",
       "      <td>00:29</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1</td>\n",
       "      <td>0.123005</td>\n",
       "      <td>0.114518</td>\n",
       "      <td>0.963900</td>\n",
       "      <td>00:14</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>2</td>\n",
       "      <td>0.080421</td>\n",
       "      <td>0.043124</td>\n",
       "      <td>0.986100</td>\n",
       "      <td>00:13</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "learn.fit_one_cycle(3, lr_max=0.1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Refactor"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def conv2(ni,nf): return ConvLayer(ni,nf,stride=2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "model = nn.Sequential(\n",
    "    conv2(1, 8),   # 14\n",
    "    conv2(8, 16),  # 7\n",
    "    conv2(16, 32), # 4\n",
    "    conv2(32, 16), # 2\n",
    "    conv2(16, 10), # 1\n",
    "    Flatten()      # remove (1,1) grid\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "learn = Learner(dls, model, loss_func = nn.CrossEntropyLoss(), metrics=accuracy)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: left;\">\n",
       "      <th>epoch</th>\n",
       "      <th>train_loss</th>\n",
       "      <th>valid_loss</th>\n",
       "      <th>accuracy</th>\n",
       "      <th>time</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>0</td>\n",
       "      <td>0.223311</td>\n",
       "      <td>0.193103</td>\n",
       "      <td>0.938700</td>\n",
       "      <td>00:12</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1</td>\n",
       "      <td>0.177194</td>\n",
       "      <td>0.145610</td>\n",
       "      <td>0.951300</td>\n",
       "      <td>00:12</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>2</td>\n",
       "      <td>0.147710</td>\n",
       "      <td>0.119839</td>\n",
       "      <td>0.961600</td>\n",
       "      <td>00:13</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>3</td>\n",
       "      <td>0.121755</td>\n",
       "      <td>0.093231</td>\n",
       "      <td>0.970300</td>\n",
       "      <td>00:12</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>4</td>\n",
       "      <td>0.112889</td>\n",
       "      <td>0.073495</td>\n",
       "      <td>0.975600</td>\n",
       "      <td>00:12</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>5</td>\n",
       "      <td>0.094216</td>\n",
       "      <td>0.065282</td>\n",
       "      <td>0.979300</td>\n",
       "      <td>00:12</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>6</td>\n",
       "      <td>0.078794</td>\n",
       "      <td>0.048146</td>\n",
       "      <td>0.985600</td>\n",
       "      <td>00:12</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>7</td>\n",
       "      <td>0.058287</td>\n",
       "      <td>0.032482</td>\n",
       "      <td>0.989300</td>\n",
       "      <td>00:12</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>8</td>\n",
       "      <td>0.046136</td>\n",
       "      <td>0.025968</td>\n",
       "      <td>0.991600</td>\n",
       "      <td>00:12</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>9</td>\n",
       "      <td>0.041037</td>\n",
       "      <td>0.026425</td>\n",
       "      <td>0.990700</td>\n",
       "      <td>00:13</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "learn.fit_one_cycle(10, lr_max=0.1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Resnet-ish"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class ResBlock(Module):\n",
    "    def __init__(self, nf):\n",
    "        self.conv1 = ConvLayer(nf,nf)\n",
    "        self.conv2 = ConvLayer(nf,nf)\n",
    "        \n",
    "    def forward(self, x): return x + self.conv2(self.conv1(x))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "model = nn.Sequential(\n",
    "    conv2(1, 8),\n",
    "    ResBlock(8),\n",
    "    conv2(8, 16),\n",
    "    ResBlock(16),\n",
    "    conv2(16, 32),\n",
    "    ResBlock(32),\n",
    "    conv2(32, 16),\n",
    "    ResBlock(16),\n",
    "    conv2(16, 10),\n",
    "    Flatten()\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def conv_and_res(ni,nf): return nn.Sequential(conv2(ni, nf), ResBlock(nf))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "model = nn.Sequential(\n",
    "    conv_and_res(1, 8),\n",
    "    conv_and_res(8, 16),\n",
    "    conv_and_res(16, 32),\n",
    "    conv_and_res(32, 16),\n",
    "    conv2(16, 10),\n",
    "    Flatten()\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "learn = Learner(dls, model, loss_func = nn.CrossEntropyLoss(), metrics=accuracy)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYIAAAEKCAYAAAAfGVI8AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAgAElEQVR4nO3deXxV9Z3/8dcn+0YSIAkhCwYIq+xEZHEBta0ruKBWW63a6lCdtk5bZ5zOdH6ddqqdaetM7VitU63WutStKi51K6iALAHCGpaQAAkEkhDIAtnuvZ/fH/dCWUIIkJNzl8/z8biP3tz7ved8OI33ne853/P9iqpijDEmckW5XYAxxhh3WRAYY0yEsyAwxpgIZ0FgjDERzoLAGGMinAWBMcZEuBi3CzhdGRkZWlBQ4HYZxhgTUlauXFmnqpmdvRdyQVBQUEBxcbHbZRhjTEgRkR0ne89ODRljTIRzLAhEJF9EFohIqYhsEJHvdNJmpog0iEhJ4PFvTtVjjDGmc06eGvIA31PVVSLSB1gpIh+q6sbj2n2mqlc7WIcxxpguONYjUNVqVV0VeN4ElAK5Tu3PGGPMmemVawQiUgBMBJZ18vY0EVkjIu+JyLkn+fw9IlIsIsW1tbUOVmqMMZHH8SAQkRTgNeB+VW087u1VwDmqOh74NfBGZ9tQ1SdVtUhVizIzOx39ZIwx5gw5GgQiEos/BJ5X1dePf19VG1W1OfD8XSBWRDKcrMn0PFVl/a4Gappa3S7FGHMGHLtYLCICPAWUquojJ2mTDexVVRWRKfiDaZ9TNZmeVX+wnddXVfHSikrKapqJj4nitqnnMG/mUDJS4t0uzxjTTU6OGpoB3AasE5GSwGs/AAYBqOoTwFzgmyLiAVqAL6utlBN0DrV7KNl5gBXb97N+dwO7D7Swp6GVfQfbAZg4KJ2fXjeGVTsO8PTiCl5YvpObz8tn9vgcJuSn4/+b4Fg+n1LT1EZcTBR9k2KPaaOqtHl8eH2KVxUBUuJjjmnj8ylV+1to83jJSk0gNSGm0/0c3t6OfYdYU3WAdVUNxMdGMWlQXyYN6kvf5Dia2zzsaWihpd3HmNzUk27HmHAlofa9W1RUpHZnsfNqmlp5f/0e3llXzYrt+/H6FBEYmplCft9EstMSyU1P4LLRAxiZnXrkc9tqm/nVR1t5b301HV4lNz2RC4dl4PEph9o9NLV62LW/har9LbR7fQDERUeR2SeeuJgoGlo6aGzpwOM79vcyNSGGgoxk8vsmUdPUSml1E81tniPvx8dEkZ4Uiyr4VPEpeH2Kz6e0e320eXxH2nl9emT7yXHRHGz3HtnOyOw+zLt4KFePG0hMtN1vacKHiKxU1aJO37MgiDyNrR0sL69nY3UjCbFRpMTHkhgXxe4DrWyrbWZbTTPrdjXgUyjMSuELowcwZXA/Jg3qS1pibLf20dDSwYcb9/LO2t2UVB4gMTaa5PgYkuNjyElPIL9fEnl9k+jw+Njb1EpNYxsen5KWGENqQizJ8THERAnRUYI38Nf/9n0Hqaw/REZKPKMGpjI6J5WkuGhqm9rY29hKY4uHqCgQEaIEokWIihJiooQhmSmMz0tn+IAUOrzKul0NrNyxn72NrWSnJTAwLYGWdi9PLapga00zeX0TmT0+h0tGZjFxUF+io6yXYEKbBUGEOnConQ837qWi7iCNrR00tXqoqDvI+sCXfGeyUxMYkplMUUE/rh43kOED+vRu0S7z+ZS/bqrh6cUVLKuox+tT0pNiuWLMQG6fdg6jBqaeeiPGBCELggji8fp4a81u3izZzeKyOjw+JSZK6JMQQ5+EWLLTEpg6pD/ThvRn4qB0PD7lYJuHg20eBqQmkBwfcvMQOqahpYPPttbycWkN762vprXDR9E5ffna9AKuGJNtp45MSLEgiACqyl/W7+Hn72+mvO4geX0TuWrcQK4aO5CxuWl2AfQsHTjUzqsrq3hu6Q527DvEoH5J3HPREOZOziMhNtrt8ow5JQuCMLanoZWPN+3l5eIq1lQeYFhWCg98aQRfGD3Avvwd4PMpH5bu5fGF2yipPEBWn3j+c+44Zo3Icrs0Y7pkQRBGDrZ5KN6xn2Xl+1hUVsfaqgYACvonce/MQq6flGunLHqBqrK0vJ5/n7+BTXua+MYFg3ng8hHEx1jvwAQnC4Igc6jdw4bdjcRECePy0k85IqWsppmPSvfy0ca9rK48gDdw3n98fjqXjsriC6MGUJiVYj0AF7R2eHno3VL+8PkOxuSm8j83T6QwK8Xtsow5gQWBy1SVtVUNvFxcyYrt9ZTVNB8ZtdM/OY6ZI7KYOqQffRJiiA+cb968p4l1uxpYW3WAyvoWAM7NSeXi4ZlMHdKfyef0tQu7QeSDDXv4x9fW0tLu5Z+vGMnt0wqIsiGnJohYELjg8N2sn2yp5aUVlZRWN5IYG835Q/oxLi+d8XlpHGz38nHpXhZurqWhpeOEbeT1TWRsbhrTh/bn0lEDyElPdOFfYrqrprGVf3ptLQs21zJ9aH9+ceN4+//MBA0Lgl5UVtPE//61jKXl9exp9E/CNnpgKreeP4g5E3Lok3DiDVker4/K/S20tHtp9Xjx+pTCzBT6Jsf1dvnmLKkqL62o5D/e3kh8bDT/e8tEphfaPIrGfRYEvWTljnrueqYYVeWi4ZmcP6Q/04b0Y2imnb+PNNtqm/m751ZSXtvMg1eM5O4Lh9jvgHFVV0FgJ5l7yEcb93LfC6vISU/kD3dNIb9fktslGRcNzUzhjftm8MAra3jo3U2s29XIz+eOs3sOTFCycYY94M2SXfzdH1cyIrsPr86bZiFgAP+Mqb/5yiQe+NII5q/Zze1PL6fh0InXgoxxmwXBWVpeUc/3X1nDlIJ+vHj3VPrbPPzmKCLCfbMKefSWiZTsPMANTyxh14EWt8sy5hgWBGehsv4Q8/64kvx+STxx22QbzmlOavb4HJ69awp7G1u57rHFFG+vd7skY46wIDiJlnYv/z5/A9Me/pgfvbWBirqDx7zf3ObhG88W4/UpT33tvG5Pz2wi17Sh/Xl13nQS46L58pNL+d1n5YTaYA0TnmzUUCdW7tjP919ZQ0XdQaYO6cfKHfvx+JSLhmWSkRLPoXaPf97+2oM8e+cULhhmwwNN9zW2dvD9l9fwwca9XDEmm1/cON56k8ZxNnz0NPx+cQU/eXsjA9MS+fnccUwvzKCmqZU/Lt3JG6t34fUpSXHRJMXHcMf0c7huYp5jtZjwpar87rMKfvaXTYzJTeOZO86z+0aMoywIuumzrbV87enlXDpqAI/cNL7Tm7+M6UkfBoYdn9Mviee+fj7ZaQlul2TCVFdBYNcIAnYdaOHbL66mMCuFX315goWA6RVfGD2AZ++cQnVDKzc8voTy2ma3SzIRyIIAaPN4ufePK+nwKk98dTJJcXa+1vSeaUP78+LdU2np8HL940tYVr7P7ZJMhLEgAB56p5Q1VQ384sbxDMm0KYRN7xubl8af751Ov+Q4vvrUMl5bWeV2SSaCOBYEIpIvIgtEpFRENojId7poe56IeEVkrlP1nExrh5eXVlRyc1E+l4/J7u3dG3PEOf2T+fM3Z1B0Tj++98oaHltQ5nZJJkI42SPwAN9T1VHAVOA+ERl9fCMRiQb+E3jfwVrYureJH721gTaP95jXl1XU0+bxccVYCwHjvrSkWJ69awqzx+fw8/c3s2BTjdslmQjgWBCoarWqrgo8bwJKgdxOmn4LeA1w9De+an8LzyzZzmdb6o55/ZPNtcTFRHH+4P5O7t6YbouLieK/5o5jZHYfvvtyCdUNNiWFcVavXCMQkQJgIrDsuNdzgeuAJ07x+XtEpFhEimtra8+ohhmFGaQlxvL22t3HvP7p1lrOH9yPxDibFdIEj4TYaB77yiTaPD6+/eJqPF6f2yWZMOZ4EIhICv6/+O9X1cbj3v4f4J9U1XviJ/9GVZ9U1SJVLcrMzDyjOuJiorhiTDYfbtxLa4d/d7sOtFBW08zFw89sm8Y4aWhmCg9dN5YV2/fz3x9tcbscE8YcDQIRicUfAs+r6uudNCkCXhKR7cBc4Dcicq1T9Vw9LoeD7d4j510/3eLvXVxkQWCC1LUTc7m5KJ/fLNx25PfVmJ7m5KghAZ4CSlX1kc7aqOpgVS1Q1QLgVeBeVX3DqZqmDulHRkocb6+tBvxBkJ2awLAsGzJqgtePZp/LsKwUvvtyCTVNrW6XY8KQkz2CGcBtwCUiUhJ4XCki80RknoP7PamY6CiuGDOQjzftpaGlg0VldVw8PNOWEDRBLTEumsdunURzm4f7XyrB6wutaWFM8HPsFlpVXQR0+xtWVe9wqpajXT1uIM8t3cEjH2ymqdVjp4VMSBg2oA8/nj2Gf3xtLb9ZUMa3Lh3mdkkmjETcncXnFfRjQGo8f1i6gyiBCwptCmkTGm4syuPaCTn890dbeG9dtdvlmDAScUEQFSVcNTYHVZiQn05akk0uZ0KDiPAf141l4qC+3PfCKl5eUel2SSZMRFwQAFwzfiBgo4VM6EmJj+G5r0/hgmGZ/ONra3ny021ul2TCQEQGwYT8dH59y0TunDHY7VKMOW1JcTH87vYirho3kIfe3cSzS7a7XZIJcRE537KIcM34HLfLMOaMxcVE8eiXJ3KozcPD75Uyc0Qm5/RPdrssE6IiskdgTDiIjhIeun4ssVFRPPjaOkJttUETPCwIjAlhA9MS+ecrR/F5+T5esovH5gxZEBgT4m6Zks+0If156J1Sm6nUnBELAmNCnIjwsxvG0uHz8Y+vrrU7j81psyAwJgyc0z+ZH149ms+21vHIh5vdLseEGAsCY8LErVMG8eXz8nlswTa789icFgsCY8KEiPDvc85lQn4633tlDVv2NrldkgkRFgTGhJH4mGie+OpkkuJi+LvnVnKo3eN2SSYEWBAYE2ay0xJ49JYJVNQd5Jcf2Mpm5tQsCIwJQ9OHZvDVqYN4enEFK3fUu12OCXIWBMaEqQevGEVOWiIPvLr2yDrdxnTGgsCYMJUSH8PD14+lvPYg//PRVrfLMUHMgsCYMHbR8ExuLsrnyU+3UVrd6HY5JkhZEBgT5n5w5SiS42P45Qd2o5npnAWBMWEuLSmWeRcP5aPSGlbu2O92OSYIWRAYEwHumF5ARkocP39/k01XbU5gQWBMBEiOj+G+WYUsLa9ncdk+t8sxQcaxIBCRfBFZICKlIrJBRL7TSZs5IrJWREpEpFhELnCqHmMi3a3nDyI3PdF6BeYETvYIPMD3VHUUMBW4T0RGH9fmY2C8qk4A7gJ+52A9xkS0+JhovnPZMNZUNfCX9XvcLscEEceCQFWrVXVV4HkTUArkHtemWf/2p0kyYH+mGOOg6yfmMjK7Dz95eyMH22weIuPXK9cIRKQAmAgs6+S960RkE/AO/l5BZ5+/J3DqqLi2ttbJUo0JazHRUfzHtWPY3dDKox/bTWbGz/EgEJEU4DXgflU94Y4WVf2zqo4ErgV+0tk2VPVJVS1S1aLMzExnCzYmzBUV9OPmonx+t6iCTXvsJjPjcBCISCz+EHheVV/vqq2qfgoMFZEMJ2syxsCDV4wkNSGGf/3zeny2tGXEc3LUkABPAaWq+shJ2hQG2iEik4A4wMa2GeOwvslx/POVoyjesZ9XVla6XY5xmZM9ghnAbcAlgeGhJSJypYjME5F5gTY3AOtFpAR4DLhZbVybMb3ixsl5TCnox8/e28T+g+1ul2NcJKH2vVtUVKTFxcVul2FMWNi0p5GrHl3ETUV5PHz9OLfLMQ4SkZWqWtTZe3ZnsTERbGR2KndOL+ClFZWs3mnzEEUqCwJjItz9XxhOVp94fvjmerx24TgiWRAYE+FS4mP416tGs35XI88v2+F2OcYFFgTGGK4eN5ALCjP4xfubaWrtcLsc08ssCIwxiAgPfGkEja0eXli20+1yTC+zIDDGADA+P50LCjP4v88qbLH7CGNBYIw54t6ZQ6lrbuOVlVVul2J6kQWBMeaIaUP7MyE/nd9+sg2P1+d2OaaXWBAYY44QEe6dOZSq/S3MX7vb7XJML7EgMMYc47JRAxg+IIXHF26zCekihAWBMeYYUVHCN2cOZcveZj7eVON2OaYXWBAYY05wzbgc8vom8vjCMlvfOAJYEBhjThATHcXdFw5h1c4DrNhucxCFOwsCY0ynbirKp19yHI8vLHO7FOMwCwJjTKcS46K5c3oBCzbXUlptS1qGMwsCY8xJ3T6tgOS4aH77yTa3SzEOsiAwxpxUWlIst0wZxPy11VTWH3K7HOMQCwJjTJe+fuFgokV43HoFvaqy/hBXPfoZ9z2/iueW7mBbbbNjI7hiHNmqMSZsDExL5Kbz8vjTikrum1VIbnqi2yVFhN8s3MbWvc3UH2znnXXVANw1YzD/ds3oHt+X9QiMMad078xCAH6zwEYQ9YbqhhZeXVnJTeflseTBS1j4/Zk8dN1Yrhyb7cj+rEdgjDmlnPREbirK5+XiSu61XoHjfvtJOT6Fv7toKCJCQUYyBRnJju3PegTGmG65d5b1CnpDbVMbL63YyXUTc8nvl9Qr+3QsCEQkX0QWiEipiGwQke900uYrIrI28FgiIuOdqscYc3Zyj+oV7D7Q4nY5YeupRRW0eXzcO3Nor+3TyR6BB/ieqo4CpgL3icjxVzkqgItVdRzwE+BJB+sxxpylw72CxxfaCCInHDjUznOfb+eqsQMZkpnSa/t1LAhUtVpVVwWeNwGlQO5xbZao6uGJTJYCeU7VY4w5e7npidwwKY+XiyupbWpzu5yw8/gn2zjY7uW+QOD2ll65RiAiBcBEYFkXzb4OvHeSz98jIsUiUlxbW9vzBRpjuu2ei4bQ7vXxzJIKt0sJK2U1TTz1WQVzJ+cxamBqr+67W0EgIkNFJD7wfKaIfFtE0rv52RTgNeB+Ve10whIRmYU/CP6ps/dV9UlVLVLVoszMzO7s1hjjkCGZKVx+bjbPfb6DptYOt8sJC6rKD9/YQFJcNA9eMbLX99/dHsFrgFdECoGngMHAC6f6kIjEBj77vKq+fpI244DfAXNUdV836zHGuGjexUNpbPXw4vKdbpcSFt5as5vPy/fxwOUjyUiJ7/X9dzcIfKrqAa4D/kdV/wEY2NUHRETwh0apqj5ykjaDgNeB21R1S/fLNsa4aXx+OtOH9g+McPG6XU5Ia2rt4KfvlDIuL41bpwxypYbuBkGHiNwCfA14O/Ba7Ck+MwO4DbhEREoCjytFZJ6IzAu0+TegP/CbwPvFp/sPMMa445szh7K3sY03Vu9yu5SQ9tiCbdQ2t/GTOWOIjhJXaujuncV3AvOAn6pqhYgMBv7Y1QdUdRHQ5b9KVb8BfKObNRhjgsgFhRmcm5PKbz8pZ+7kfNe+xEKZqjJ/zW4uHTmA8fnduuzqiG71CFR1o6p+W1VfFJG+QB9V/ZnDtRljgpiIcN+sQsrrDh6ZFM2cnrKaZnYdaOGSkVmu1tHdUUMLRSRVRPoBa4Dfi0in5/2NMZHj8nOzGZaVwv/+dSs+ny1yf7oWbvYPh585wt3RkN29RpAWGPp5PfB7VZ0MXOZcWcaYUBAVJfz9JYVs2dvMBxv3uF1OyFm4pYbhA1LIcXkSv+4GQYyIDARu4m8Xi40xhqvH5TAkI5lHPy5zbOGUcHSwzcOKiv3MHOHuaSHofhD8GHgf2KaqK0RkCLDVubKMMaEiOkq4d1YhG6sb+bi0xu1yQsaSbfto9/q4eLj7N8l292LxK6o6TlW/Gfi5XFVvcLY0Y0yomDMhh/x+ifz6r1utV9BNCzfXkBQXTVFBX7dL6fbF4jwR+bOI1IjIXhF5TURsgjhjDACx0VHcO7OQNVUNLCqrc7ucoKeqLNxcy/ShGcTHRLtdTrdPDf0eeAvIwT+D6PzAa8YYA8D1k3LJ6hPPE7bI/Sltq/UPG3V7tNBh3Q2CTFX9vap6Ao9ngOD4FxhjgkJ8TDTfuHAwi8v2sabygNvlBLVgGTZ6WHeDoE5Evioi0YHHVwGbIM4Yc4xbpgwiNSHGegWn8MmWWgqzUsjr2ztLUZ5Kd4PgLvxDR/cA1cBc/NNOGGPMEX0SYrl9WgF/2bCHbbXNbpcTlFo7vCyrqOeiYcHRG4DujxraqaqzVTVTVbNU9Vr8N5cZY8wx7phRQFx0FE9+Uu52KUFpeUU97R4fFw7PcLuUI85mhbLv9lgVxpiwkZESz01F+by+uorqBlvk/niLy+qIjRbOH9zP7VKOOJsgsKkGjTGduvvCIXR4lT+tqHS7lKCzqKyOSYP6khTX3cmfnXc2QWB3jRhjOjWofxLThvTn9VW77Aazo+xrbmPD7kYuKAye00JwiiAQkSYRaezk0YT/ngJjjOnUDZPz2Fl/iBXb97tdStBYss0/2PKCYSEUBKraR1VTO3n0UdXg6dcYY4LOFWOySYqL5rWVVW6XEjQWl9XRJyGGsblpbpdyjLM5NWSMMSeVHB/D5WOyeWddNS3ttq6xqvLZ1jqmD+1PTHRwffUGVzXGmLAyd1IezW0eW6sA2LHvELsOtATd9QGwIDDGOGjqkP7kpifyqp0eOjIZ3wVBdCPZYRYExhjHREUJ103MZXFZHXsaWt0ux1WLttaRm55IQf/gmFbiaBYExhhHXT8pF5/C66sjt1fg9SlLttVxQWEGIsF3C5ZjQSAi+SKyQERKRWSDiHynkzYjReRzEWkTke87VYsxxj1DMlOYMrgfzy/dicfrc7scV7y9djeNrR4uDpLZRo/nZI/AA3xPVUcBU4H7RGT0cW3qgW8Dv3CwDmOMy+6aUcCuAy18VLrX7VJ63YFD7fx4/kYm5KfzpXOz3S6nU44FgapWq+qqwPMmoBT/ojZHt6lR1RVAh1N1GGPc94XR2eT1TeTpRdvdLqXXPfzuJg60dPDw9WOJjgq+00LQS9cIRKQAmAgsO8PP3yMixSJSXFtb25OlGWN6QXSUcMf0ApZvr2f9rga3y+k1S8v38afiSr5x4WBGDUx1u5yTcjwIRCQFeA24X1Ubz2QbqvqkqhapalFmZnCeYzPGdO3GonyS4qJ5enGF26X0ijaPlx/8eR35/RK5/9LhbpfTJUeDQERi8YfA86r6upP7MsYEt7TEWG6cnMf8NbupaQr/oaQvLttJee1B/uPasSTGub9AfVecHDUkwFNAqao+4tR+jDGh444Zg+nwKs8v3el2KY5SVV5aUcm4vDQuHh78ZzGc7BHMAG4DLhGRksDjShGZJyLzAEQkW0Sq8C9y868iUiUiwXsizRhzVgZnJHPJyCxeWB7eQ0nXVjWwaU8TN5+X73Yp3eLYDKKquohTLF6jqnuAPKdqMMYEn5uK8vnrpho+21rHrJFZbpfjiJdWVJIQG8U140Njtn67s9gY06suGZlFv+S4sJ1/6FC7h/lrdnPV2BxSE2LdLqdbLAiMMb0qLiaKORNy+HDjXg4cane7nB73ztpqmts8IXNaCCwIjDEuuHFyPu1eH2+t2e12KT3uTysqGZKRzHkFfd0updssCIwxvW50TiqjB6aG3emhsppminfs56bz8oNycrmTsSAwxrhi7uQ81lY1sHlPk9ul9Jhnl2wnJkq4flLuqRsHEQsCY4wrrp2YS2y08OrKSrdL6RELNtXw3NId3DJlEFl9Etwu57RYEBhjXNEvOY5LRmbx59W76AjxewqqG1r47ssljBqYyr9cNcrtck6bBYExxjVzJ+dT19zOJ5tDdzJJj9fHt15YTbvHx2O3TiQhNrink+iMBYExxjUzR2SSkRLHKyF6ekhV+a/3N1O8Yz8PXT+WIZkpbpd0RiwIjDGuiY2O4toJuXxcWsO+5ja3yzktHq+PH765nic/LeerUwcxZ0JoXSA+mgWBMcZVNxbl4/Epb5aEzj0FB9s83P2HYv64dCfzLh7Kj2ePcbuks2JBYIxx1YjsPozLSwuZewo27G5g7hOf8+nWOh66biwPXjGSqCBdeay7LAiMMa6bOzmPjdWNbNgdvKuXHTjUzg/fWM81v15ETWMrT32tiFvPH+R2WT3CgsAY47rZ43OIi47ileLg7BWsq2rgkl9+wvPLdnD7tAL++v2ZzBwRPjOnWhAYY1yXnhTHF0YP4M2SXbR7guuegtYOL//wcgnxMVG88+0L+dHsc0lLDI1ZRbvLgsAYExTmFuWx/1AHf91U43Ypx3j0462U1TTzsxvGBfUC9GfDgsAYExQuLMygf3Ic84NoRtJ1VQ389tNybpycFxJLTp4pCwJjTFCIiY7i6nED+ah0L02tHW6XQ7vHxwOvriEjJY5/vXq02+U4yoLAGBM0Zk/Ipc3j44MNe90uhacXV7BpTxMPXTc27K4JHM+CwBgTNCYNSievb2JQLFgzf81uzivoy6WjBrhdiuMsCIwxQUNEmD0+h0VlddS5OOXE3sZWNuxu5JKR4R8CYEFgjAkycybk4vUp766rdq2Gw7OhzhoZvheIj+ZYEIhIvogsEJFSEdkgIt/ppI2IyKMiUiYia0VkklP1GGNCw4jsPozM7uPq3EMLNtcwMC2BEQP6uFZDb3KyR+ABvqeqo4CpwH0icvyl9yuAYYHHPcDjDtZjjAkRsyfksHLHfirrD/X6vju8Pj7bWsfMEVkhte7w2XAsCFS1WlVXBZ43AaXA8fO0zgH+oH5LgXQRGehUTcaY0HDNuBwA5q/t/V7Biu31NLd5mDUiMk4LQS9dIxCRAmAisOy4t3KBo1ekqOLEsEBE7hGRYhEprq0N3ZWMjDHdk98vifH56a4MI124uZbYaGFGYUav79stjgeBiKQArwH3q2rj8W938hE94QXVJ1W1SFWLMjMjJ6WNiWRfHD2AksoD7G1s7dX9LthUw/mD+5McH9Or+3WTo0EgIrH4Q+B5VX29kyZVQP5RP+cB7g8gNsa47ouj/UM3P9zYe72CyvpDbK1pZmYEnRYCZ0cNCfAUUKqqj5yk2VvA7YHRQ1OBBlV1b8yYMSZoFGalMDgjmQ96MQgWbjk8bDR8ppjuDif7PjOA24B1IlISeO0HwCAAVX0CeBe4EigDDgF3OliPMSaEiAhfHD2ApxdX0NjaQWqC89M8LNhUw6B+SQzJSHZ8X8HEsSBQ1UV0fg3g6DYK3OdUDQjyiicAAAv2SURBVMaY0PbFcwfw20/L+WRzLdeMz3F0X3sbW/l0Sy13XTA4YoaNHmZ3FhtjgtaE/L5kpMT1yumhl5ZX4vEpt04Jj+UnT4cFgTEmaEVHCZeNGsCCTTW0ebyO7cfj9fHi8p1cOCyDggg7LQQWBMaYIPfFcwfQ3OZhaXm9Y/v4qLSGPY2t3Db1HMf2EcwsCIwxQW360AyS4qL5YMMex/bxx6U7yElL4JIIGy10mAWBMSaoJcRGM2tEFu9v2IPH2/ML25fXNrOorI5bzx9ETHRkfiVG5r/aGBNSrhmfQ11zO4u37evxbT+/bCex0cJN5+WfunGYsiAwxgS9WSMzSU2I4c3Vu3p0u60dXl4pruRL52aT1SehR7cdSiwIjDFBLz4mmivHDuT9DXtoae+50UPLK+ppbPVw/aQT5rqMKBYExpiQMHtCDgfbvXxU2nP3FCzYXEN8TBTThkTOTKOdsSAwxoSEqYP7k52awJslPXd6aOHmWqYN7U9iXHSPbTMUWRAYY0JCVJQwe0IOCzfXsv9g+1lvr6LuIBV1B5k1IjKHjB7NgsAYEzJmj8/B41PeXX/2kxQv2FQDYEGABYExJoScm5NKYVYKb64++2VLFmyuYWhmMoP6J/VAZaHNgsAYEzJEhNnjc1i+vZ6apjNfuexQu4dl5fXWGwiwIDDGhJTD00B8uqXujLexpGwf7V5fxC1AczIWBMaYkHJuTiqZfeJZsLnmjLexYHMNyXHRFBX07cHKQpcFgTEmpIgIM4dn8tmW2jOae0hVWbi5lhmFGcTHRPaw0cMsCIwxIWfmiCwaWz2UVB447c9urWlm14EWOy10FAsCY0zIuWBYBtFRckanhz7b6r+2cNHwzJ4uK2RZEBhjQk5aYiyTB/Vl4eba0/7s0vJ9DOqXRG56ogOVhSYLAmNMSLp4RCYbdjdS09j9YaRen7KsfB/ThvR3sLLQY0FgjAlJh+8BWLil+72C0upGGls9TBtqQXA0x4JARJ4WkRoRWX+S9/uKyJ9FZK2ILBeRMU7VYowJP6MG9mFAajyfnMbpoaXl/oVtplqP4BhO9gieAS7v4v0fACWqOg64HfiVg7UYY8KMiHDx8Ew+3dr9YaSfb9vH4IxkstMidxGazjgWBKr6KVDfRZPRwMeBtpuAAhEZ4FQ9xpjwM2tEFk2tHpZv7+qrxs/j9bG8ot56A51w8xrBGuB6ABGZApwD5HXWUETuEZFiESmurT39UQLGmPB08YhMkuKimb/m1JPQbaxupKnNw9Qh/XqhstDiZhD8DOgrIiXAt4DVgKezhqr6pKoWqWpRZqaN/TXG+CXFxfClc7N5Z201bZ6ul7D8PLDwvY0YOpFrQaCqjap6p6pOwH+NIBOocKseY0xomjMhh8ZWDws2dX224PPyfQzNTCYr1a4PHM+1IBCRdBGJC/z4DeBTVW10qx5jTGi6oDCDjJQ43lh98iUsPV4fKyrqbdjoScQ4tWEReRGYCWSISBXw/4BYAFV9AhgF/EFEvMBG4OtO1WKMCV8x0VFcPS6HF5btpKGlg7TE2BParNvVwMF2r10oPgnHgkBVbznF+58Dw5zavzEmclw3MZdnlmznvXXVfHnKoBPeX7LN7h/oit1ZbIwJeePy0hickcwbJZ2fHnpvfTXj89LISInv5cpCgwWBMSbkiQjXTshlaXk9uw+0HPNeWU0z63c1MntCrkvVBT8LAmNMWLh2Yg4Ar66sOub1t9bsRgSuGTfQjbJCggWBMSYsnNM/mUtGZvHUogqaWjsA/2pk89fsZtqQ/jZstAsWBMaYsHH/ZcNoaOngmcXbAf9ooYq6g8yZkONuYUHOgsAYEzbG5aVz2ags/u+zchpaOnizZDdx0VFcfq6dFuqKBYExJqzcf9lwGls9PLWogvlrdjNzRCZpSSfeW2D+xrH7CIwxxg1jctP44ugBPLagDK9PmW2nhU7JegTGmLBz/2XD8fqU5LhoLh1ps9ufivUIjDFhZ3ROKndfOJg+CbEkxkW7XU7QsyAwxoSlf7lqtNslhAw7NWSMMRHOgsAYYyKcBYExxkQ4CwJjjIlwFgTGGBPhLAiMMSbCWRAYY0yEsyAwxpgIJ6rqdg2nRURqgR1u19FDMoA6t4sIYnZ8umbHp2t2fI51jqpmdvZGyAVBOBGRYlUtcruOYGXHp2t2fLpmx6f77NSQMcZEOAsCY4yJcBYE7nrS7QKCnB2frtnx6Zodn26yawTGGBPhrEdgjDERzoLAGGMinAWBMcZEOAuCICUiUSLyUxH5tYh8ze16gpGIJIvIShG52u1ago2IXCsi/ycib4rIF92uJxgEfl+eDRyXr7hdTzCxIHCAiDwtIjUisv641y8Xkc0iUiYiD55iM3OAXKADqHKqVjf00PEB+CfgZWeqdE9PHB9VfUNV7wbuAG52sFxXneaxuh54NXBcZvd6sUHMRg05QEQuApqBP6jqmMBr0cAW4Av4v9hXALcA0cDDx23irsBjv6r+VkReVdW5vVW/03ro+IzDP4VAAlCnqm/3TvXO64njo6o1gc/9EnheVVf1Uvm96jSP1RzgPVUtEZEXVPVWl8oOOrZ4vQNU9VMRKTju5SlAmaqWA4jIS8AcVX0YOOHUhohUAe2BH73OVdv7euj4zAKSgdFAi4i8q6o+RwvvJT10fAT4Gf4vvrAMATi9Y4U/FPKAEuxsyDEsCHpPLlB51M9VwPldtH8d+LWIXAh86mRhQeK0jo+q/guAiNyBv0cQFiHQhdP9/fkWcBmQJiKFqvqEk8UFmZMdq0eB/xWRq4D5bhQWrCwIeo908tpJz8up6iHg686VE3RO6/gcaaD6TM+XEpRO9/fnUfxffJGo02OlqgeBO3u7mFBg3aPeUwXkH/VzHrDbpVqCkR2frtnx6T47VqfJgqD3rACGichgEYkDvgy85XJNwcSOT9fs+HSfHavTZEHgABF5EfgcGCEiVSLydVX1AH8PvA+UAi+r6gY363SLHZ+u2fHpPjtWPcOGjxpjTISzHoExxkQ4CwJjjIlwFgTGGBPhLAiMMSbCWRAYY0yEsyAwxpgIZ0FgwoKINPfy/n4nIqN7aFteESkRkfUiMl9E0k/RPl1E7u2JfRsDdh+BCRMi0qyqKT24vZjAjUmOO7p2EXkW2KKqP+2ifQHw9uFpl405W9YjMGFLRDJF5DURWRF4zAi8PkVElojI6sD/jgi8foeIvCIi84EPRGSmiCwUkVdFZJOIPB+Y3pnA60WB583iX01ujYgsFZEBgdeHBn5eISI/7mav5XP8s2ciIiki8rGIrBKRdSIyJ9DmZ8DQQC/i54G2DwT2s1ZE/r0HD6OJABYEJpz9CvhvVT0PuAH4XeD1TcBFqjoR+DfgoaM+Mw34mqpeEvh5InA//nUPhgAzOtlPMrBUVcfjnzL87qP2/6vA/k856VlgQZVL+du8OK3Adao6CZgF/DIQRA8C21R1gqo+IP6lKIfhn4d/AjA5sGCLMd1i01CbcHYZMDrwRzxAqoj0AdKAZ0VkGP6pnGOP+syHqlp/1M/LVbUKQERKgAJg0XH7aQcOr5C2Ev/KWOAPlWsDz18AfnGSOhOP2vZK4MPA6wI8FPhS9+HvKQzo5PNfDDxWB35OwR8MkbCOhekBFgQmnEUB01S15egXReTXwAJVvS5wvn3hUW8fPG4bbUc999L5fzMd+reLbSdr05UWVZ0gImn4A+U+/GsJfAXIBCaraoeIbMe/NOfxBHhYVX97mvs1BrBTQya8fYB/FkoARGRC4GkasCvw/A4H978U/ykp8E+F3CVVbQC+DXxfRGLx11kTCIFZwDmBpk1An6M++j5wl4gcvuCcKyJZPfRvMBHAgsCEi6TANMSHH9/F/6VaFLiAuhGYF2j7X8DDIrIY/+LvTrkf+K6ILAcGAg2n+oCqrgbW4A+O5/HXX4y/d7Ap0GYfsDgw3PTnqvoB/lNPn4vIOuBVjg0KY7pkw0eNcYiIJOE/7aMi8mXgFlWdc6rPGdPb7BqBMc6ZjH+xdAEOAHe5XI8xnbIegTHGRDi7RmCMMRHOgsAYYyKcBYExxkQ4CwJjjIlwFgTGGBPhLAiMMSbC/X8NG2kU+y984wAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "learn.lr_find(end_lr=100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: left;\">\n",
       "      <th>epoch</th>\n",
       "      <th>train_loss</th>\n",
       "      <th>valid_loss</th>\n",
       "      <th>accuracy</th>\n",
       "      <th>time</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>0</td>\n",
       "      <td>0.183473</td>\n",
       "      <td>0.492155</td>\n",
       "      <td>0.854100</td>\n",
       "      <td>00:18</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1</td>\n",
       "      <td>0.133731</td>\n",
       "      <td>0.188146</td>\n",
       "      <td>0.945000</td>\n",
       "      <td>00:17</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>2</td>\n",
       "      <td>0.089143</td>\n",
       "      <td>0.080600</td>\n",
       "      <td>0.974100</td>\n",
       "      <td>00:18</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>3</td>\n",
       "      <td>0.084515</td>\n",
       "      <td>0.052463</td>\n",
       "      <td>0.981700</td>\n",
       "      <td>00:18</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>4</td>\n",
       "      <td>0.061913</td>\n",
       "      <td>0.044865</td>\n",
       "      <td>0.987100</td>\n",
       "      <td>00:18</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>5</td>\n",
       "      <td>0.057088</td>\n",
       "      <td>0.059705</td>\n",
       "      <td>0.981400</td>\n",
       "      <td>00:18</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>6</td>\n",
       "      <td>0.054864</td>\n",
       "      <td>0.034580</td>\n",
       "      <td>0.988600</td>\n",
       "      <td>00:18</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>7</td>\n",
       "      <td>0.035986</td>\n",
       "      <td>0.031446</td>\n",
       "      <td>0.989900</td>\n",
       "      <td>00:17</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>8</td>\n",
       "      <td>0.032535</td>\n",
       "      <td>0.022280</td>\n",
       "      <td>0.992800</td>\n",
       "      <td>00:19</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>9</td>\n",
       "      <td>0.026329</td>\n",
       "      <td>0.018659</td>\n",
       "      <td>0.994300</td>\n",
       "      <td>00:17</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>10</td>\n",
       "      <td>0.020302</td>\n",
       "      <td>0.016571</td>\n",
       "      <td>0.994500</td>\n",
       "      <td>00:18</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>11</td>\n",
       "      <td>0.020105</td>\n",
       "      <td>0.016252</td>\n",
       "      <td>0.995300</td>\n",
       "      <td>00:17</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "learn.fit_one_cycle(12, lr_max=0.05)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Sequential (Input shape: 128 x 1 x 28 x 28)\n",
      "================================================================\n",
      "Layer (type)         Output Shape         Param #    Trainable \n",
      "================================================================\n",
      "Conv2d               128 x 8 x 14 x 14    72         True      \n",
      "________________________________________________________________\n",
      "BatchNorm2d          128 x 8 x 14 x 14    16         True      \n",
      "________________________________________________________________\n",
      "ReLU                 128 x 8 x 14 x 14    0          False     \n",
      "________________________________________________________________\n",
      "Conv2d               128 x 8 x 14 x 14    576        True      \n",
      "________________________________________________________________\n",
      "BatchNorm2d          128 x 8 x 14 x 14    16         True      \n",
      "________________________________________________________________\n",
      "ReLU                 128 x 8 x 14 x 14    0          False     \n",
      "________________________________________________________________\n",
      "Conv2d               128 x 8 x 14 x 14    576        True      \n",
      "________________________________________________________________\n",
      "BatchNorm2d          128 x 8 x 14 x 14    16         True      \n",
      "________________________________________________________________\n",
      "ReLU                 128 x 8 x 14 x 14    0          False     \n",
      "________________________________________________________________\n",
      "Conv2d               128 x 16 x 7 x 7     1,152      True      \n",
      "________________________________________________________________\n",
      "BatchNorm2d          128 x 16 x 7 x 7     32         True      \n",
      "________________________________________________________________\n",
      "ReLU                 128 x 16 x 7 x 7     0          False     \n",
      "________________________________________________________________\n",
      "Conv2d               128 x 16 x 7 x 7     2,304      True      \n",
      "________________________________________________________________\n",
      "BatchNorm2d          128 x 16 x 7 x 7     32         True      \n",
      "________________________________________________________________\n",
      "ReLU                 128 x 16 x 7 x 7     0          False     \n",
      "________________________________________________________________\n",
      "Conv2d               128 x 16 x 7 x 7     2,304      True      \n",
      "________________________________________________________________\n",
      "BatchNorm2d          128 x 16 x 7 x 7     32         True      \n",
      "________________________________________________________________\n",
      "ReLU                 128 x 16 x 7 x 7     0          False     \n",
      "________________________________________________________________\n",
      "Conv2d               128 x 32 x 4 x 4     4,608      True      \n",
      "________________________________________________________________\n",
      "BatchNorm2d          128 x 32 x 4 x 4     64         True      \n",
      "________________________________________________________________\n",
      "ReLU                 128 x 32 x 4 x 4     0          False     \n",
      "________________________________________________________________\n",
      "Conv2d               128 x 32 x 4 x 4     9,216      True      \n",
      "________________________________________________________________\n",
      "BatchNorm2d          128 x 32 x 4 x 4     64         True      \n",
      "________________________________________________________________\n",
      "ReLU                 128 x 32 x 4 x 4     0          False     \n",
      "________________________________________________________________\n",
      "Conv2d               128 x 32 x 4 x 4     9,216      True      \n",
      "________________________________________________________________\n",
      "BatchNorm2d          128 x 32 x 4 x 4     64         True      \n",
      "________________________________________________________________\n",
      "ReLU                 128 x 32 x 4 x 4     0          False     \n",
      "________________________________________________________________\n",
      "Conv2d               128 x 16 x 2 x 2     4,608      True      \n",
      "________________________________________________________________\n",
      "BatchNorm2d          128 x 16 x 2 x 2     32         True      \n",
      "________________________________________________________________\n",
      "ReLU                 128 x 16 x 2 x 2     0          False     \n",
      "________________________________________________________________\n",
      "Conv2d               128 x 16 x 2 x 2     2,304      True      \n",
      "________________________________________________________________\n",
      "BatchNorm2d          128 x 16 x 2 x 2     32         True      \n",
      "________________________________________________________________\n",
      "ReLU                 128 x 16 x 2 x 2     0          False     \n",
      "________________________________________________________________\n",
      "Conv2d               128 x 16 x 2 x 2     2,304      True      \n",
      "________________________________________________________________\n",
      "BatchNorm2d          128 x 16 x 2 x 2     32         True      \n",
      "________________________________________________________________\n",
      "ReLU                 128 x 16 x 2 x 2     0          False     \n",
      "________________________________________________________________\n",
      "Conv2d               128 x 10 x 1 x 1     1,440      True      \n",
      "________________________________________________________________\n",
      "BatchNorm2d          128 x 10 x 1 x 1     20         True      \n",
      "________________________________________________________________\n",
      "ReLU                 128 x 10 x 1 x 1     0          False     \n",
      "________________________________________________________________\n",
      "Flatten              128 x 10             0          False     \n",
      "________________________________________________________________\n",
      "\n",
      "Total params: 41,132\n",
      "Total trainable params: 41,132\n",
      "Total non-trainable params: 0\n",
      "\n",
      "Optimizer used: <function Adam at 0x7effc0232440>\n",
      "Loss function: CrossEntropyLoss()\n",
      "\n",
      "Model unfrozen\n",
      "\n",
      "Callbacks:\n",
      "  - TrainEvalCallback\n",
      "  - Recorder\n",
      "  - ProgressCallback\n"
     ]
    }
   ],
   "source": [
    "print(learn.summary())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## fin"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "jupytext": {
   "split_at_heading": true
  },
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
